<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map-demo</title>
        <script src="https://cdn.bootcss.com/three.js/r83/three.min.js"></script>
        <script type="text/javascript" src="./inflate.min.js"></script>
        <script type="text/javascript" src="./OrbitControls.js"></script>
        <script type="text/javascript" src="./WebGL.js"></script>
        <script type="text/javascript" src="./stats.min.js"></script>
		<script type="text/javascript" src="./lodash.js"></script>
        <style type="text/css">
            
            html,body {
                width: 100%;
                height: 100%;
                padding: 0px;
                margin: 0px;
            }

            div#canvas-frame {
                padding: 0px;
                margin: 0px;
                border: none;
                cursor: pointer;
                width: 100%;
                height: 100%;
                background-color: #EEEEEE;
                overflow: hidden;
            }
        </style>
        <script>
            var renderer;
            function initThree() {
                width = document.getElementById('canvas-frame').clientWidth;
                height = document.getElementById('canvas-frame').clientHeight;
                renderer = new THREE.WebGLRenderer({
                    antialias : true
                });
                renderer.setSize(width, height);
                document.getElementById('canvas-frame').appendChild(renderer.domElement);
                renderer.setClearColor(0xFFFFFF, 1.0);
            }

            var camera,controls;
            function initCamera() {
                //参考 https://www.cnblogs.com/v-weiwang/p/6072235.html 
                camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
                //相机的位置
                /*
                camera.position.x = 1600;
                camera.position.y = 1200;
                camera.position.z = 0;
                */
                camera.position.x = 0;
                camera.position.y = 2000;
                camera.position.z = 0;
                //相机以哪个方向为上方
                camera.up.x = 0;
                camera.up.y = 1;
                camera.up.z = 0;
                //相机看向哪个坐标
                camera.lookAt({
                    x : 0,
                    y : 0,
                    z : 0
                });
                //引入第三方相机控制库
                controls = new THREE.OrbitControls( camera );
                controls.target.set( 0, 100, 0 );
                controls.update();
            }

            var scene;
            function initScene() {
                scene = new THREE.Scene();
            }

            var light;
            function initLight() {
                light = new THREE.DirectionalLight(0xFF0000, 1.0, 0);
                light.position.set(100, 100, 200);
                scene.add(light);
            }

            var cubeList= [];
            function initObject() {
                //创建物体
                var cubeGeometry = new THREE.BoxGeometry(50, 50 ,50);
                for (var j = -15; j < 15; j++) {
                    for (var i = -15; i < 15; i++) {
                        //创建物体材质
                        var material = new THREE.MeshBasicMaterial( {color: 0xffffff} );
                        //添加物体材质
                        var cube = new THREE.Mesh(cubeGeometry, material);
                        //物品定位
                        cube.position.z = 50 * j;
                        cube.position.x = 50 * i;
                        //创建边缘线条
                        var edgesMtl =  new THREE.LineBasicMaterial({color: 0x000000,linewidth:1});
                        //几何辅助线
                        // THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.
                        var cubeEdges = new THREE.EdgesGeometry(cubeGeometry, 1);
                        // edgesMtl.depthTest = false;
                        //创建线条对象
                        var cubeLine = new THREE.LineSegments(cubeEdges, edgesMtl);
                        //物品添加辅助线
                        cube.add(cubeLine);
						cubeList.push(cube);
                        //console.log(142,cube);
                        //放入场景
                        scene.add(cube);
                    }
                }
            }
            
            //点击事件  声明raycaster和mouse变量
            var raycaster = new THREE.Raycaster();
            var mouse = new THREE.Vector2();
            function onMouseClick( event ) {
                console.log('onMouseClick');
                //通过鼠标点击的位置计算出raycaster所需要的点的位置，以屏幕中心为原点，值的范围为-1到1.
                mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
                mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
                // 通过鼠标点的位置和当前相机的矩阵计算出raycaster
                raycaster.setFromCamera( mouse, camera );
                // 获取raycaster直线和所有模型相交的数组集合
                var intersects = raycaster.intersectObjects( scene.children )
                console.log(intersects);
                //将所有的相交的模型的颜色设置为红色，如果只需要将第一个触发事件，那就数组的第一个模型改变颜色即可
                if (intersects.length > 0) {
                  //intersects[0].object.material.color.set( 0xff0000 );
                }
                /*
                for ( var i = 0; i < intersects.length; i++ ) {
                    intersects[ i ].object.material.color.set( 0xff0000 );
                }
                */
            }  
            window.addEventListener( 'click', onMouseClick, false );
            
            /****创建贪吃蛇******/
			var intervalID;
			var foodObj = {
				num:'',
				obj:''
			};
			var itemDel;
			//蛇对象
            var snake = {
				time : 300, //定时刷新时间
				num : 50,   //立方体大小      
				color : '#0000ff', //贪吃蛇颜色 蓝色 食物是红色
				d : 'T', //缓存当前蛇运动方向 上:	T 下D 左 L 右 R
				cp : [
				   {x:0,y:0,z:0,obj:''},//默认起点坐标
				   {x:0,y:0,z:50,obj:''} 
				]//缓存每块对象坐标,碰撞检测
			};
			
			//上色
			function setP(sp) {
				for (var i in cubeList) {
					var p = cubeList[i].position;
					//console.log(165,p);
					if (p.x == sp.x && p.y == sp.y && p.z== sp.z) {
						cubeList[i].material.color.set(snake.color);
						sp.obj = cubeList[i];
						sp.num = i;
					} 
				}
		    }

            //初始化
            function run() {
			    for (var i in snake.cp) {
                   setP(snake.cp[i]);
			    }
            }
			
			//游戏结束
			function gameOver() {
			    window.clearInterval(intervalID);
			    alert('game over!');
			}
			
			//判断是否碰撞到边界
			function boxBorder() {
			    if (snake.cp[0].x < -750 || snake.cp[0].z < -750 || snake.cp[0].x > 750 || snake.cp[0].y > 750) {
			      gameOver();
			      return false;
			    };
				return true;
			}

			//移动
			function moveSnake() {
				snake.cp = countMoveNum();
				//判断边界
				var bool = boxBorder();
				if (bool) {
					//判断食物
					checkFood();
				    run();
				}
			}
			
			//判断食物
			function checkFood() {
				var start = snake.cp[0];
				if (start.num == foodObj.num) {
					snake.cp.push(itemDel);
					randomFood();
				}
			}

			//计算移动量,删除尾巴,增加头部
			function countMoveNum() {
				var arr = _.clone(snake.cp);
				if (snake.d == 'T') {
					var p = _.clone(arr[0]);
					    p.z = p.z - snake.num;
				    itemDel = arr.pop();
					itemDel.obj.material.color.set('#ffffff');
					arr.unshift(p);
				} else if (snake.d == 'D') {
					var p = _.clone(arr[0]);
					    p.z = p.z + snake.num;
					itemDel = arr.pop();
					itemDel.obj.material.color.set('#ffffff');
					arr.unshift(p);
				} else if (snake.d == 'R') {
					var p = _.clone(arr[0]);
					    p.x = p.x + snake.num;
					itemDel = arr.pop();
					itemDel.obj.material.color.set('#ffffff');
					arr.unshift(p);
				} else if (snake.d == 'L') {
					var p = _.clone(arr[0]);
					    p.x = p.x - snake.num;
					itemDel = arr.pop();
					itemDel.obj.material.color.set('#ffffff');
					arr.unshift(p);
				}
				return arr;
			}
			
			//定时器
			function interval() {
			    intervalID = window.setInterval(function(){
			      moveSnake();
			    },1000);
			}
			
			//绑定方向键
			function bindEvt() {  
			    document.onkeyup = function(e){
					var  e   =   window.event||e,   
						 k   =   e.keyCode||e.which;
				    switch(k) {
						 case 37 :
						    if (snake.d !== 'L' && snake.d !=='R') {
							   snake.d = 'L';
						    }
						 break;
						 case 38 :
						    if (snake.d !== 'T' && snake.d !=='D') {
							  snake.d = 'T';
						    }
						 break;
						 case 39 :
						    if (snake.d !== 'L' && snake.d !=='R') {
							  snake.d = 'R';
						    }
						 break;
						 case 40 :
						    if (snake.d !== 'T' && snake.d !=='D') {
							  snake.d = 'D';
						    }
						 break;
					}       
			     };
			}
			
			//随机函数
			function randomNum(){
			    var num = Math.floor(Math.random()*(1 - 900) + 900);
				return num;
			}
			
			//食物
			function randomFood() {
				var num = randomNum();
				foodObj.num = num;
				foodObj.obj = cubeList[num];
			    cubeList[num].material.color.set('#ff0000');
			}
			
            function threeStart() {
                initThree();
                initCamera();
                initScene();
                initLight();
                initObject();
				
				bindEvt();
				run();
				interval();
				randomFood();
				
                renderer.clear();
                render();
            }

            function render() {
                requestAnimationFrame(render);
                renderer.render(scene, camera);
            }

        </script>
    </head>

    <body onload="threeStart();">
        <div id="canvas-frame"></div>
    </body>
</html>